﻿using System;
using System.Collections.Generic;

namespace MentalAlchemy.Molecules.MachineLearning
{
	[Serializable]
	public class WeightedKnnClassifier : KnnClassifier
	{
		/// <summary>
		/// Get ID of the class using information about distances between object under consideration and distances to all training samples. The decision is based upon weighted voting among k closest objects.
		/// </summary>
		/// <param name="dists">Array of distances to all training samples.</param>
		/// <param name="clIds">Class IDs of the training samples.</param>
		/// <param name="curK">Neighborhood size.</param>
		/// <returns>ID of the winning class.</returns>
		public override int GetWinningClassId(List<float> dists, List<int> clIds, int curK, int clCount)
		{
			// get k first objects and make voting for the particular class.
			var clVotes = new float[classCount];
			for (var i = 0; i < curK; ++i)
			{
				clVotes[clIds[i]] += (float)Math.Exp(-dists[i]);
			}

			int classId = 0;
			var maxVote = clVotes[0];
			for (var i = 1; i < clVotes.Length; ++i)
			{
				if (maxVote < clVotes[i])
				{
					classId = i;
					maxVote = clVotes[i];
				}
			}

			return classId;
		}
	}
}
